<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <div id="app">
      <p>{{name}} === {{age}}</p>
      <p>{{arr}}</p>
    </div>
    <script src="../dist/vue.js"></script>
    <script>
      /*
				Vue 是 MVVM 框架，（基于 MVC升级，弱化 Controller），有没有完全遵循 mvvm，因为传统 mvvm 框架是不能手动操作数据的，在 vue 中可以手动通过 ref 去操作组件数据 

				Vue2 的核心：响应式原理， 使用 defineProperty 来监听数据的变化
        
        双向绑定主要体现在 v-model 上
        
        vm.$options 获取到用户传递所有参数

        vue2 中 $开头的属性，是不会变成响应式的，用户如果传递了带有 $的属性会被忽略，处理掉， data:{"$a": 124} vm.$a是获取不到的返回undefined

        vue2 的数据源 props data methods computed watch
				
        vue2 数组修改数据后实在麻烦就直接覆盖原始数据，暴力


        vue2中的响应式原理就是为对象的每个属性 添加 set 和 get，会递归遍历，因此，用户在写代码的时候对data的数据的对象嵌套不要太过于深，
        vue2中数组的长度和索引没有监控，
        vue2中的数组没有采用 defineProperty ，采用了函数的劫持重写的数组的 7 个方法，用户在调用的时候或执行这个这个方法，用户添加数据时会再次被劫持，后再执行数据的原生方法，因此数组中的对象也是响应式的

        渲染 Watcher： 是默认是创建一个组件，就会生成一个渲染 Watcher，
        v-if 在数据切换后， 需要再重新收集依赖


        依赖收集的流程
        一开始就走 defineReactive 方法把每个属性劫持监听，此时会个每个属性配置对应的 Dep（Dep 的目的是为了收集渲染 Wathcer）
        开始渲染组件之前，把组件的每个 Watcher 先绑定到 Dep.target 上
        开始渲染逻辑就会调用 render 方法，此时发生取值操作，去触发 get 函数，此时 Dep.target 上有对应的渲染 Watcher，就让 dep 和 watcher 创建关系，此时属性中就对应了dep中欧给你的存放的数组 watchers用来存储哪个watcher用到了该属性，同样watcher也会存储这依赖的所有属性 deps
        每个属性有一个 dep，dep记住了对应的watcher

        React 本身是一个 V 框架，只是将数据转换成试图，并没有绑定操作，更新数据也是手动调用 setState 去更新的
        react 的数据源主要在 props 和 state data
			*/
      const vm = new Vue({
        el: "#app",
        data: function () {
          return {
            name: "Timly",
            age: 100,
            arr: [1, 2, 3],
          };
        },
      });

      const t = setTimeout(() => {
        vm.name = "1111";
        vm.name = "2222";
        vm.name = "3333";
        vm.age = 10000;

        vm.$nextTick(() => {
          console.log("$nextTick");
          const app = document.querySelector("#app");
          console.log(app.innerHTML);
        });
        console.log("setTimeout1");
        // 暴力手动调用更新视图
        // vm._update(vm._render()); // 不用手动调用了，让自己的渲染 Watcher 自己去调用
        clearTimeout(t);

        const tt = setTimeout(() => {
          vm.arr.push(1111);
          vm.arr.push(2222);
          vm.arr.push(3333);
          console.log("setTimeout2");
          clearTimeout(tt);
        }, 2000);
      }, 2000);
      console.log(vm, vm.$options);
    </script>
  </body>
</html>
